﻿namespace Viz
{
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Windows;
    using System.Windows.Graphics;
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;

    public class Plot
    {
        public static VertexPositionColor[] Create(
            float                                       x1, 
            float                                       x2, 
            float                                       z1, 
            float                                       z2, 
            int                                         count,
            Func<float, float, float>                   function,
            bool                                        mirr
        )
        {
            return Create(x1, x2, (float) ((x2 - x1) / count),  z1, z2, (float) ((z2 - z1) / count), function, mirr);
        }

        public static VertexPositionColor[] Create(
            float                                       x1, 
            float                                       x2, 
            float                                       incx, 
            float                                       z1, 
            float                                       z2, 
            float                                       incz, 
            Func<float, float, float>                   function,
            bool                                        mirr
        )
        {
            var dev = GraphicsDeviceManager.Current.GraphicsDevice;
            if (dev != null)
            {
                Color color1 = System.Windows.Media.Colors.Yellow.ToColor();
                Color color2 = System.Windows.Media.Colors.Blue.ToColor();
                int   i = 0;

                var plot = new List<VertexPositionColor>();
                for (float x = x1; x <= x2; x += incx)
                {
                    if (incz != 0)
                    {
                        for (float z = z1; z <= z2; z += incz)
                        {
                            foreach (var item in CreateRectangle(i % 2 == 0 ? color1: color2, x, z, incx, incz, function, mirr))
                            {
                                plot.Add(item);
                            }
                            ++i;
                        }
                    }
                    else
                    {
                        foreach (var item in CreateRectangle(i % 2 == 0 ? color1: color2, x, z1, incx, incz, function, mirr))
                        {
                            plot.Add(item);
                        }
                        ++i;
                    }
                }
                return plot.ToArray();
            }
            else
            {
                return null;
            }
        }

        private static IEnumerable<VertexPositionColor> CreateRectangle(
            Color                                       color, 
            float                                       x, 
            float                                       z, 
            float                                       incx, 
            float                                       incz, 
            Func<float, float, float>                   function,
            bool                                        mirr
        )
        {
            Vector3 leftFront  = new Vector3(x       , function(x, z)              , z);
            Vector3 rightFront = new Vector3(x + incx, function(x + incx, z)       , z);
            Vector3 leftBack   = new Vector3(x       , function(x, z + incz)       , z + incz);
            Vector3 rightBack  = new Vector3(x + incx, function(x + incx, z + incz), z + incz);

            yield return new VertexPositionColor(leftBack,   color);
            yield return new VertexPositionColor(rightBack,  color);
            yield return new VertexPositionColor(leftFront,  color);
            yield return new VertexPositionColor(rightBack,  color);
            yield return new VertexPositionColor(rightFront, color);
            yield return new VertexPositionColor(leftFront,  color);

            if (mirr)
            {
                leftFront  = new Vector3(x       , -function(x, z)              , z);
                rightFront = new Vector3(x + incx, -function(x + incx, z)       , z);
                leftBack   = new Vector3(x       , -function(x, z + incz)       , z + incz);
                rightBack  = new Vector3(x + incx, -function(x + incx, z + incz), z + incz);

                yield return new VertexPositionColor(leftBack,   color);
                yield return new VertexPositionColor(rightBack,  color);
                yield return new VertexPositionColor(leftFront,  color);
                yield return new VertexPositionColor(rightBack,  color);
                yield return new VertexPositionColor(rightFront, color);
                yield return new VertexPositionColor(leftFront,  color);
            }
        }
    }
}
